package com.suncreate.radarscan.service;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.suncreate.commons.AlertEventDetectThread;
import com.suncreate.commons.KafkaConsumerThread;
import com.suncreate.radarscan.dao.AlertEventEntityMapper;
import com.suncreate.radarscan.dao.RadarConfigEntityMapper;
import com.suncreate.radarscan.dao.RadarInfoEntityMapper;
import com.suncreate.radarscan.dao.RadarLaneEntityMapper;
import com.suncreate.radarscan.entity.RadarConfigInfoEntity;
import com.suncreate.radarscan.entity.RadarLaneEntity;
import com.suncreate.radarscan.model.Lane;
import com.suncreate.radarscan.model.Polygon;
import com.suncreate.radarscan.model.Radar;
import com.suncreate.radarscan.model.RawRadarData;
import com.suncreate.radarscan.model.Road;

@Service
public class AlertEventDetectService {
	//日志记录        
    private Logger logger = LoggerFactory.getLogger(AlertEventDetectService.class);
	
	@Autowired
	RadarConfigEntityMapper radarConfigDao;
	
	@Autowired
	RadarLaneEntityMapper radarLaneDao;
	
	@Autowired
	RadarInfoEntityMapper radarInfoDao;
	
	@Autowired
	AlertEventEntityMapper alertEventDao;
	
	List<RadarConfigInfoEntity> radarConfigInfoList;

	/**雷达关联的缓存队列
	 *1.key:雷达序列号（radarNo)
	 *2.value:存放对应雷达的缓存队列
	 */
	public static Map<String,LinkedBlockingQueue<RawRadarData>> rawDataQueueMap = new HashMap<String,LinkedBlockingQueue<RawRadarData>>();
	
	/**雷达关联的道路信息
	 * 1.key:雷达序列号（radarNo)
	 * 2.value:对应的道路信息
	 */
	public static Map<String,Road> roadMap = new HashMap<String,Road>();
	
	/**雷达信息
	 * 1.key:雷达序列号（radarNo)
	 * 2.value:对应的雷达信息
	 */
	public static Map<String,Radar> radarMap = new HashMap<String,Radar>();
	
	//将各个雷达数据插入到不同的LinkedBlockingQueue中
	public void radarDataInit() {
		for(RadarConfigInfoEntity radarConfigInfo:this.radarConfigInfoList) {
			KafkaConsumerThread consumerThread = new KafkaConsumerThread(radarConfigInfo.getPartitionNum(),radarConfigInfo.getRadarNo());
			Thread t = new Thread(consumerThread);
			t.setName(radarConfigInfo.getRadarNo()+":" + radarConfigInfo.getPartitionNum()+"consumer");
			t.start();
			logger.debug("启动一个线程去读取雷达对应的kafka数据到缓存队列中，线程ID为:" + t.getId() + ",该线程对应的雷达序列号为：" + radarConfigInfo.getRadarNo() + ",读取的分区号为:" + radarConfigInfo.getPartitionNum() );
		}
	}
//	@Autowired
//	Test test;
	public void startEventDetect() {
		
//		test.Write();
		//初始化 1.雷达信息 2道路信息 3.缓存队列
		logger.debug("开始初始化各雷达信息、雷达对应道路信息、雷达对应缓存队列");
		init();
		logger.debug("各雷达信息、雷达对应道路信息、雷达对应缓存队列初始化完毕");
		
		//针对每一个雷达启动一个线程去分析报警事件
		for (Map.Entry<String,Radar> entry : radarMap.entrySet()) {
			String radarNo = entry.getKey();
			Thread t = new AlertEventDetectThread(entry.getValue(),roadMap.get(radarNo),this.alertEventDao);
			t.setName(radarNo+"detect");
			t.start();
			logger.debug("启动了一个线程去事件检测，该线程的线程Id为:" + t.getId()+",该线程对应的雷达信息为:" + entry.getValue().toString() +",该线程对应的道路信息为:" + roadMap.get(radarNo).toString());
		}
		
		//向每个雷达对应的缓存队列中插入雷达原始数据
		radarDataInit();
	}
	
	//初始化 1.雷达信息 2道路信息 3.缓存队列
	public void init() {
		//获取雷达信息，里面有雷达Id,然后根据雷达Id获取各雷达关联的道路信息
		this.radarConfigInfoList = radarConfigDao.selectAllRadarConfigInfo();
		logger.debug("联合查询数据库中dr3_radar_config与dr3_radar_info表,获取当前系统内所有雷达信息，目前系统内总共有" + this.radarConfigInfoList.size() + "个雷达！");
		
		//Radar初始化，初始化系统内各雷达信息
		logger.debug("开始初始化系统内各雷达信息!");
		radarInit();
		logger.debug("系统内各雷达信息初始化完毕!");
		
		//Road初始化,初始化系统内各雷达关联的道路信息
		logger.debug("开始初始化各雷达对应的道路信息");
		roadInit();
		logger.debug("各雷达对应的道路信息初始化完毕");
		
		//初始化各雷达缓存队列
		logger.debug("开始初始化各雷达对应的缓存队列");
		rawDataQueueMapInit();
		logger.debug("各雷达对应的缓存队列初始化完毕");
		
	}
	
	public void rawDataQueueMapInit() {
		for(RadarConfigInfoEntity radarConfigInfo:this.radarConfigInfoList) {
			AlertEventDetectService.rawDataQueueMap.put(radarConfigInfo.getRadarNo(), new LinkedBlockingQueue<RawRadarData>());
			logger.debug("缓存队列初始化成功，雷达序列号为:" + radarConfigInfo.getRadarNo());
		}
	}

	/**
	 * @Description: 系统内各雷达关联的道路初始化 ，根据从radar_config表中查询到的雷达Id，然后根据雷达Id查询radar_lane表获取道路信息并完成初始化
	 * @param radarConfigList 雷达信息列表,查询radar_config表
	 * @return 无
	 */
	public void roadInit() {
		for(RadarConfigInfoEntity radarConfigInfo:this.radarConfigInfoList) {
			//根据radarId查询雷达对应的道路信息
			List<RadarLaneEntity> radarLaneList = radarLaneDao.selectAllLaneByRadarId(radarConfigInfo.getRadarId());
			//根据查询到的道路信息构建道路对象Road
			Road road = new Road();
			List<Lane> laneList = new ArrayList<Lane>();
			
			//将RadarLaneEntity转换为Lane对象
			for(RadarLaneEntity radarLane:radarLaneList) {
				Lane lane = new Lane();
				lane.setNotRoad((radarLane.getLaneType()==1)?true:false);
				lane.setRealLineLeft((radarLane.getLaneLeft()==1)?true:false);
				lane.setRealLineRight((radarLane.getLaneRight()==1)?true:false);
				lane.setRightDirection((radarLane.getLaneDirectioin()==1)?true:false);
				lane.setMaxSpeed(radarLane.getLaneSpeedLimit().doubleValue());
				lane.setWidth(radarLane.getLaneWidth().doubleValue());
				laneList.add(lane);
			}
			
			road.setxAxe(0);//此参数暂时在程序中写死，各Road对象都参照单机版设置为0.
			road.setLanes(laneList);
			
			AlertEventDetectService.roadMap.put(radarConfigInfo.getRadarNo(), road);
			logger.debug("单个雷达对应的道路信息初始化完毕，道路信息详情为:" + road.toString());
		}
	}
	
	//初始化系统内各雷达信息
	public void radarInit() {
		Radar radar = new Radar();
		for(RadarConfigInfoEntity radarConfigInfo:this.radarConfigInfoList) {
			radar.setRadarNo(radarConfigInfo.getRadarNo());
			//检测线
			List<Double> detectLinesList = new ArrayList<Double>();
			detectLinesList.add(new Double(radarConfigInfo.getRadarDetectLineTop()));//上检测线
			detectLinesList.add(new Double(radarConfigInfo.getRadarDetectLineBottom()));//下检测线
			detectLinesList.add(new Double(radarConfigInfo.getRadarDetectLineLeft()));//左检测线
			detectLinesList.add(new Double(radarConfigInfo.getRadarDetectLineRight()));//右检测线
			radar.setDetectLines(detectLinesList);
			
			//根据检测线绘制检测区域
			Polygon poly = new Polygon();
			poly.setLegal(true);
			poly.setLevel(2);
			poly.setLineColor("yellow");
			List<Point2D.Double> points = new ArrayList<Point2D.Double>();
			points.add(new Point2D.Double(radarConfigInfo.getRadarDetectLineLeft(), radarConfigInfo.getRadarDetectLineTop()));
			points.add(new Point2D.Double(radarConfigInfo.getRadarDetectLineLeft(), radarConfigInfo.getRadarDetectLineBottom()));
			points.add(new Point2D.Double(radarConfigInfo.getRadarDetectLineRight(), radarConfigInfo.getRadarDetectLineTop()));
			points.add(new Point2D.Double(radarConfigInfo.getRadarDetectLineRight(), radarConfigInfo.getRadarDetectLineBottom()));
			poly.setPoints(points);
			poly.setName("检测区域");
			List<Polygon> polyList = new ArrayList<Polygon>();
			polyList.add(poly);
			radar.setDetectAreas(polyList);
			
			radar.setRadarDistance(radarConfigInfo.getRadarDistance());
			radar.setRadarHeight(radarConfigInfo.getRadarHeight());
			radar.setRadarPitch(radarConfigInfo.getRadarPitch());
			radar.setRadarRange(radarConfigInfo.getRadarPitch());
			radar.setRadarSlope(radarConfigInfo.getRadarSlope());
			radar.setxAxe(radarConfigInfo.getxAxe());  //X坐标
			radar.setyAxe(radarConfigInfo.getyAxe()); //Y坐标
			
			AlertEventDetectService.radarMap.put(radarConfigInfo.getRadarNo(), radar);
			logger.debug("成功初始化单个雷达，雷达详细信息为:" + radar.toString());
		}
	}
	
}
